﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EpidemicSimulator.states;
using QuickGraph;
using EdgeWithAttributes;

namespace EpidemicSimulator.strategies
{
    public class VaccinateNaighbourStrategy: StateChangeStrategy
    {
        #region StateChangeStrategy Members

        public void applyStrategy(QuickGraph.UndirectedGraph<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>> socialNetwork, QuickGraph.AdjacencyGraph<DiseaseModelNode, DiseaseModelEdge> diseaseModelGraph, int numOfUnits)
        {
            DiseaseModelNode immunizedState = null;
            foreach (DiseaseModelNode diseaseModelNode in diseaseModelGraph.Vertices)
            {
                if (diseaseModelNode.stateName == "Immunized")
                {
                    immunizedState = diseaseModelNode;
                    break;
                }
            }

            SocialNetworkNode[] nodes = socialNetwork.Vertices.ToArray();
            Random random = new Random();
            while (numOfUnits > 0)
            {
                int r = random.Next(nodes.Length);
                SocialNetworkNode randomNode = randomNaighbour(socialNetwork, nodes[r]);
                if (randomNode.state.stateNode.stateName == "Susceptible")
                {
                    int maxContactsPerStep = randomNode.state.maxContacsPerStep;
                    int minContactsPerStep = randomNode.state.minContacsPerStep;
                    randomNode.state = State.getStateInstance(immunizedState.stateClass);
                    randomNode.state.stateNode = immunizedState;
                    randomNode.state.diseaseModelGraph = diseaseModelGraph;
                    randomNode.state.node = randomNode;
                    randomNode.state.maxContacsPerStep = maxContactsPerStep;
                    randomNode.state.minContacsPerStep = minContactsPerStep;
                    randomNode.newState = randomNode.state;
                    numOfUnits--;
                }
            }
        }

        #endregion

        private static SocialNetworkNode randomNaighbour(UndirectedGraph<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>> socialNetwork, SocialNetworkNode node)
        {
            List<SocialNetworkNode> nodeList = new List<SocialNetworkNode>();
            foreach (var e in socialNetwork.AdjacentEdges(node))
            {
                if (e.Source.Equals(node))
                {
                    if (!nodeList.Contains(e.Target))
                    {
                        nodeList.Add(e.Target);
                    }
                }
                if (e.Target.Equals(node))
                {
                    if (!nodeList.Contains(e.Source))
                    {
                        nodeList.Add(e.Source);
                    }
                }
            }
            var nodeArray = nodeList.ToArray();
            if (nodeArray.Length == 0)
            {
                return node;
            }
            Random random = new Random();
            return nodeArray[random.Next(nodeArray.Length)];
        }
    }
}
